/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package fr.inria.openmath.omapi;

/**
 *
 * @author Mr.Sam
 */
import java.util.Vector;

/**
 * Defines tree like access/construction API for OpenMath objects
 * (similar to the level 1 core DOM API)
 *
 * The <code>Node</code> interface represents a single node in the tree.
 * While all objects implementing the <code>Node</code> interface expose
 * methods for dealing with children, not all objects implementing the
 * <code>Node</code> interface may have children. For example,
 * <code>Float</code> nodes have no children, and adding children to such
 * nodes results in a <code>OMException</code> being raised.
 */
public interface Node {

    /**
     * NodeType
     * These values are those of the C library and they have been carefully
     * chosen to make encoding autodetection easy.
     */
    public static final byte OM_UKNOWN = 0;

    public static final byte OM_INT32 = 1;

    public static final byte OM_BIGINT = 2;

    public static final byte OM_FLOAT64 = 3;

    public static final byte OM_BYTEARRAY = 4;

    public static final byte OM_VAR = 5;

    public static final byte OM_STRING = 6;

    public static final byte OM_SYMBOL = 8;

    public static final byte OM_PINSTRUCTION = 14;

    public static final byte OM_COMMENT = 15;

    public static final byte OM_APP = 16;

    public static final byte OM_ERROR = 22;

    public static final byte OM_OBJECT = 24;

    public static final byte OM_BIND = 26;


    /**
     * These are not real nodes (rather tags)
     * they are used mainly in binary encoding
     */
    public static final byte OM_END_APP = 17;

    public static final byte OM_ATTR = 18;

    public static final byte OM_END_ATTR = 19;

    public static final byte OM_ATP = 20;

    public static final byte OM_END_ATP = 21;

    public static final byte OM_END_ERROR = 23;

    public static final byte OM_END_OBJECT = 25;

    public static final byte OM_END_BIND = 27;

    public static final byte OM_BVAR = 28;

    public static final byte OM_END_BVAR = 29;

    /**
     * constants used for binary encoding
     */
    public static final byte OM_WCSTRING = 7;/* tag wide char strings */

    public static final byte OM_BE_POS_BASE_10 = '+';/* 2B */

    public static final byte OM_BE_NEG_BASE_10 = '-';/* 2C */

    public static final byte OM_BE_POS_BASE_16 = (OM_BE_POS_BASE_10 +
            (1 << 6));/* 0x40 + '+' */

    public static final byte OM_BE_NEG_BASE_16 = (OM_BE_NEG_BASE_10 +
            (1 << 6));/* 0x40 + '-' */

    /**
     * In binary encoding when len of token is > 255
     * this bit mask is ored to token type
     * following len field is encoded on 4 bytes rather
     * than on only one
     */
    public static final byte OM_BE_BIG_LEN_MASK = (byte) (0x80);/* 1000 0000 */

    /**
     * In binary encoding if an object is in fact a reference
     * to a previously seen one, this bit mask is ored to
     * token type
     */
    public static final byte OM_BE_SHARED_MASK = (byte) (0x40);/* 0100 0000 */


    /**
     * The name of this node, depending on its type; see the table above.
     */
    public String getNodeName() ;

    /**
     * A code representing the type of the underlying object, as defined above.
     */
    public short getNodeType() ;


    /**
     * The parent of this node.
     * All nodes, except the root <code><OMOBJ></code> have a parent.
     * However, if a node has just been created and not yet added to the tree,
     * or if it has been removed from the tree, this is <code>null</code>.
     */
    public Node getParent() ;

    /**
     * This is a convenience method to allow easy determination of whether a
     * node has any children.
     * @return  <code>true</code> if the node has any children,
     *   <code>false</code> if the node has no children.
     */
    public boolean hasChildNodes() ;

    /**
     * A <code>NodeList</code> that contains all children of this node.
     * If there are no children, this is a <code>NodeList</code> containing
     * no nodes.
     * The content of the returned <code>NodeList</code> is "live" in the sense
     * that, for instance, changes to the children of the node object that
     * it was created from are immediately reflected in the nodes returned by
     * the <code>NodeList</code> accessors; it is not a static snapshot of the
     * content of the node.
     * @see #hasChildNodes()
     */
    public NodeList getChildNodes() ;

    /**
     * The first child of this node. If there is no such node, this returns
     * <code>null</code>.
     */
    public Node getFirstChild() ;

    /**
     * The last child of this node. If there is no such node, this returns
     * <code>null</code>.
     */
    public Node getLastChild() ;

    /**
     * The node immediately preceding this node. If there is no such node, this
     * returns <code>null</code>.
     */
    public Node getPreviousSibling() ;

    /**
     * The node immediately following this node. If there is no such node, this
     * returns <code>null</code>.
     */
    public Node getNextSibling() ;

    /**
     * Inserts the node <code>newChild</code> before the existing child node
     * <code>refChild</code>. If <code>refChild</code> is <code>null</code>,
     * insert <code>newChild</code> at the end of the list of children.
     * If the <code>newChild</code> is already in the tree, it is first
     * removed.
     * @param newChild The node to insert.
     * @param refChild The reference node, ie: the node before which the new
     *   node must be inserted.
     * @return The node being inserted.
     * @exception OMException
     *   OME_HIERARCHY_REQUEST: Raised if this node is of a type that
     *   does not allow children, or if the node to insert is one of this
     *   node's ancestors.
     *   <br>OME_NODE_NOT_FOUND: Raised if <code>refChild</code> is not
     *   a child of this node.
     */
    public Node insertBefore(Node newChild, Node refChild) throws OMException ;

    /**
     * Replaces the child node <code>oldChild</code> with <code>newChild</code>
     * in the list of children, and returns the <code>oldChild</code> node. If
     * the <code>newChild</code> is already in the tree, it is first removed.
     * @param newChild The new node to put in the child list.
     * @param oldChild The node being replaced in the list.
     * @return The node replaced.
     * @exception OMException
     *   OME_HIERARCHY_REQUEST: Raised if this node is of a type that does not
     *   allow children, or if the node to put in is one of this node's
     *   ancestors.
     *   <br>OME_NOT_FOUND: Raised if <code>oldChild</code> is not a child of
     *   this node.
     */
    public Node replaceChild(Node newChild, Node oldChild) throws OMException ;

    /**
     * Removes the child node indicated by <code>oldChild</code> from the list
     * of children, and returns it.
     * @param oldChild The node being removed.
     * @return The node removed.
     * @exception OMException
     *   OME_NOT_FOUND: Raised if <code>oldChild</code> is not a child of
     *   this node.
     */
    public Node removeChild(Node oldChild) throws OMException ;

    /**
     * Adds the node <code>newChild</code> to the end of the list of
     * children of this node. If the <code>newChild</code> is already in
     * the tree, it is first removed.
     * @param newChild The node to add.
     * @return The node added.
     * @exception OMException
     *   OME_HIERARCHY_REQUEST: Raised if this node is of a type that does not
     *   allow children, or if  the node to append is one of this node's
     *    ancestors.
     */
    public Node appendChild(Node newChild) throws OMException ;


    /**
     * Returns a duplicate of this node, ie: serves as a generic copy
     * constructor for nodes. The duplicate node has no parent
     * (<code>parentNode</code> returns <code>null</code>.).
     * All attributes or comments are also copied.
     * @param deep If <code>true</code>, recursively clone the subtree under
     *  the specified node;
     *  if <code>false</code>, clone only the node itself (and its attributes
     *  and comments).
     * @return The duplicate node.
     */
    public Node cloneNode(boolean deep) ;

    /**
     * Retrieves an attribute's value (a node) given its name (a Symbol)
     * @param name Name of attribute to retrieve.
     * @return A <code>Node</code> linked with the specified attribute's name, or
     *   <code>null</code> if the specified attribute has not been set on this <code>Node</code>.
     */
    public Node getAttribute(Symbol name) ;

    /**
     * Adds an attribute value using its name.
     * If an attribute with that name has already been set
     * on this node, nothing is specified. (implementation
     * specific behavior)
     * (DOM is slightly different at this point)
     */
    public void setAttribute(Symbol name, Node value) ;

    /**
     * Removes am attribute specified by name.
     * @param name The name of attribute to remove.
     * @return The node removed from the map or <code>null</code>.
     */
    public Node removeAttribute(Symbol name) ;

    /**
     * The number of attributes set on this node. The range of valid
     * attribute indices is 0 to <code>length-1</code> inclusive.
     * @see #getNthAttributeValue()
     * @see #getNthAttributeName()
     */
    public int getAttributeNumber() ;

    /**
     * Returns the <code>index</code>th attribute value. If <code>index</code>
     * is greater than or equal to the number of attributes set on this node,
     * this returns <code>null</code>.
     * @param index Index of attribute.
     * @return The attribute's value (node) at the <code>index</code>th
     *  position, or <code>null</code> if that is not a valid index.
     */
    public Node getNthAttributeValue(int index) ;

    /**
     * Returns the <code>index</code>th attribute name. If <code>index</code>
     * is greater than or equal to the number of attributes set on this node,
     * this returns <code>null</code>.
     * @param index Index of attribute.
     * @return The attribute's name (symbol) at the <code>index</code>th
     * position, or <code>null</code> if that is not a valid index.
     */
    public Symbol getNthAttributeName(int index) ;

    /**
     * Get the comments that have been set on this node.
     * @return the comment string of this node or <code>null</code>.
     */
    public String getComments() ;

    /**
     * Set the comments on this node.
     * @return the old comment string of this node or <code>null</code>.
     */
    public String setComments(String comment) ;

    /**
     * Get the vector of strings that represents all the
     * processing instructions that have been set on this node.
     * @return the vector of processing instructions strings for this node or <code>null</code>.
     */
    public Vector getPInstructions() ;

    /**
     * Set the vector of strings that represents all the
     * processing instructions of this node.
     * @return the old vector of this node or <code>null</code>.
     */
    public Vector setPInstructions(Vector pis) ;

}
